package com.cctc.juc.common.util;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * [反射] 工具类。
 */
public class ReflectionUtil {

    /**
     * 生成目标对象的代理实例。
     */
    public static Object newProxyInstance(Object targetObject, InvocationHandler handler) {
        Class targetClass = targetObject.getClass();
        return Proxy.newProxyInstance(targetClass.getClassLoader(),
                                      getInterfaces(targetClass),
                                      handler);
    }

    /**
     * 获取目标类及其父类所实现的所有接口清单。
     */
    public static Class<?>[] getInterfaces(Class<?> targetClass) {
        Set<Class<?>> interfaces = new HashSet<>();
        List<Class<?>> tmp = Arrays.asList(targetClass.getInterfaces());
        if (tmp.size() > 0) interfaces.addAll(tmp);
        Class superClass = targetClass.getSuperclass();
        while (null != superClass) {
            tmp = Arrays.asList(superClass.getInterfaces());
            if (tmp.size() > 0) interfaces.addAll(tmp);
            superClass = superClass.getSuperclass();
        }
        return interfaces.toArray(new Class<?>[0]);
    }

    /**
     * 获取当前线程调用方法栈帧中的方法名称。
     */
    public static String getCallMethod() {
        StackTraceElement[] stack = Thread.currentThread().getStackTrace();
        String method = stack[3].getMethodName();
        return method;
    }

    /**
     * 获取当前线程调用方法栈帧中的类名称 + 方法名称。
     * 格式：[类.方法]。
     */
    public static String getCallClassAndMethod() {
        StackTraceElement stack[] = Thread.currentThread().getStackTrace();
        String[] className = stack[3].getClassName().split("\\.");
        String clazz = className[className.length - 1];
        String method = stack[3].getMethodName();
        return clazz + "." + method;
    }

}
